import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ProcessXMLOutput {
	
	private float waitingTime, crashes, meanTravelTime;
   private Constant constant;


   float laneSampleSeconds[]    = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneTravelTime[]       = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneDensity[]          = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneOccupancy[]        = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneWaitingTime[]      = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneSpeed[]            = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneVehiclesEntered[]  = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   float laneVehiclesLeft[]     = new float[constant.MAX_NUMBER_OF_XML_ELEMENTS];

   double laneAvgNumVehicles[]                             = new double[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   double laneAvgTrafficVolume_CarsPerHour[]               = new double[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   double laneAvgTrafficVolumeExitingLane_CarsPerHour[]    = new double[constant.MAX_NUMBER_OF_XML_ELEMENTS];
   
	public ProcessXMLOutput(){	  
      parseXMLOutput();
   }

   private void parseXMLOutput() {
      float loaded, emitted;

      try {
         File file = new File(Parameters.sumoOutputPath, Parameters.sumoOutputFile);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         Document doc = db.parse(file);
         doc.getDocumentElement().normalize();

         NodeList nodeLst;
         nodeLst = doc.getElementsByTagName(Parameters.sumoOutputRootXMLTag);

         Node fstNode = nodeLst.item(nodeLst.getLength() - 1);

         waitingTime    = Float.parseFloat(unmarshallAttribute(fstNode, "meanWaitingTime", "999"));
         meanTravelTime = Float.parseFloat(unmarshallAttribute(fstNode, "meanTravelTime", "999"));

         loaded = Float.parseFloat(unmarshallAttribute(fstNode, "loaded", "999"));
         emitted = Float.parseFloat(unmarshallAttribute(fstNode, "emitted", "999")) + Float.parseFloat(unmarshallAttribute(fstNode, "waiting", "999"));

         if (loaded > emitted) {
            crashes = 1;
         }

      } catch (Exception e) {
         e.printStackTrace();
      }

      //Parse for occupancy
      try {
         File file = new File(Parameters.sumoOutputPath, Parameters.sumoLaneStatisticsOutputFile);
		   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		   DocumentBuilder db = dbf.newDocumentBuilder();
		   Document doc = db.parse(file);
		   doc.getDocumentElement().normalize();
         
         NodeList nodeLst = doc.getElementsByTagName("lane");

           //BUG - This assumes that the sample time is the same as the simulation time. If not, this will fail.
           for (int i=0; i<nodeLst.getLength(); i++)
           {
              Node lane = nodeLst.item(i);
              laneSampleSeconds[i]   = Float.parseFloat(unmarshallAttribute(lane,"sampledSeconds" , "-1"));
              laneTravelTime[i]      = Float.parseFloat(unmarshallAttribute(lane,"traveltime"     , "-1"));
              laneDensity[i]         = Float.parseFloat(unmarshallAttribute(lane,"density"        , "-1"));
              laneOccupancy[i]       = Float.parseFloat(unmarshallAttribute(lane,"occupancy"      , "-1"));
              laneWaitingTime[i]     = Float.parseFloat(unmarshallAttribute(lane,"waitingTime"    , "-1"));
              laneSpeed[i]           = Float.parseFloat(unmarshallAttribute(lane,"speed"          , "-1"));
              laneVehiclesEntered[i] = Float.parseFloat(unmarshallAttribute(lane,"entered"        , "-1"));
              laneVehiclesLeft[i]    = Float.parseFloat(unmarshallAttribute(lane,"left"           , "-1"));

              //Derive further Statistics
              laneAvgNumVehicles[i] = laneSampleSeconds[i] / 3.6;
              laneAvgTrafficVolume_CarsPerHour[i] = (laneSpeed[i] * laneDensity[i]) / 3.6;
              laneAvgTrafficVolumeExitingLane_CarsPerHour[i] = (3600 * laneVehiclesLeft[i]) / Parameters.meanLaneDataSampleTimeSeconds;
              //System.out.println("Lane " + i + " = " + laneOccupancy[i]);
           }//end for
        }//end try
        catch (Exception e) 
        {
		     e.printStackTrace();
		  }//end catch
	}
	
	private String unmarshallAttribute( Node node, String name, String defaultValue ){
		Node n = node.getAttributes().getNamedItem( name );
		return (n!=null)?(n.getNodeValue()):(defaultValue);
	}
	
	public float getWaitingTime(){
		return waitingTime;
	}
	
	public float getMeanTravelTime(){
		return meanTravelTime;
	}
	
	public float getCrashes(){
		return crashes;
	}

   //See Constant class for indexes to specific lanes.
	public float[] getOccupancy(){
		return laneOccupancy;
	}

   public float[] getLaneWaitingTime(){
      return laneWaitingTime;
   }


   //Get Individual Statistics
   public float[] getLaneMeanTravelTime()
   {
      return laneTravelTime;
   }

   public float[] getMeanDensity()
   {
      return laneDensity;
   }

   public float[] getMeanOccupancy()
   {
      return laneOccupancy;
   }


   public float[] getMeanWaitingTime()
   {
      return laneWaitingTime;
   }

   public float[] getMeanSpeed()
   {
      return laneSpeed;
   }

   public float[] getVehiclesEntered()
   {
      return laneVehiclesEntered;
   }

   public float[] getVehiclesLeft()
   {
      return laneVehiclesLeft;
   }

   public double[] getAvgNumVehicles()
   {
      return laneAvgNumVehicles;
   }

   public double[] getAvgTrafficVolumeCarsPerHour()
   {
      return laneAvgTrafficVolume_CarsPerHour;
   }


   public double[] getAvgTrafficVolumeExitingLaneCarsPerHour()
   {
      return laneAvgTrafficVolumeExitingLane_CarsPerHour;
   }

           

}
